#pragma once
#include <unordered_map>
#include <functional>
#include "Common.hpp"
#include "Protocol_Netcal.hpp"

using cal_t = std::function<int(int, int)>;

enum cal_retcode{
    DEVIDE_ZERO = 0,
    MOD_ZERO,
    UNKNOW_OPR
};

class Calculator{
public:
    Calculator(){
        _calculator.emplace('+', [](int left, int right)->int{return left + right;});
        _calculator.emplace('-', [](int left, int right)->int{return left - right;});
        _calculator.emplace('*', [](int left, int right)->int{return left * right;});
        _calculator.emplace('/', [](int left, int right)->int{return left / right;});
        _calculator.emplace('%', [](int left, int right)->int{return left % right;});
    }

    Response Calculate(int left, int right, char opr) {
        Response res(0, 0);
        if(_calculator.find(opr) == _calculator.end()) 
            res.SetRetCode(UNKNOW_OPR);
        else{
            if(opr == '%' && right == 0) res.SetRetCode(MOD_ZERO);
            if(opr == '/' && right == 0) res.SetRetCode(DEVIDE_ZERO);
            else res.SetResult(_calculator[opr](left, right)); 
        }
        return res;
    }

    ~Calculator(){}

private:
    std::unordered_map<char, cal_t> _calculator;
};